package com.ruoyi.factory.taskShow.service.impl;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.factory.common.domain.AjaxBean;

import com.ruoyi.factory.taskShow.domain.TaskShow;
import com.ruoyi.factory.taskShow.domain.TaskShowTreeSelect;
import com.ruoyi.factory.taskShow.service.SysTaskShowService;
import com.ruoyi.factory.common.utils.IdGen;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import com.ruoyi.factory.taskShow.mapper.TaskShowMapper;

/**
 * @ClassName SysTaskShowServiceImpl
 * @Description TODO
 * @Author liujiaji
 * @Date 2022/6/20 15:08
 */
@Service
public class SysTaskShowServiceImpl implements SysTaskShowService
{
    @Autowired
    private TaskShowMapper taskShowMapper;

    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public TaskShow selectTaskShowById(String id)
    {
        return taskShowMapper.selectTaskShowById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param taskShow 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<TaskShow> selectTaskShowList(TaskShow taskShow)
    {
        List<TaskShow> taskShows = taskShowMapper.selectTaskShowList(taskShow);
        return taskShows;
    }


    /**
     * @Description //TODO y分子  z分母
     * @Author liujiaji
     * @Date 2022/6/27 15:12
     * @Param [y, z]
     * @return java.lang.String
     **/
    public static String myPercent(long y, long z) {
        String baifenbi = "";// 接受百分比的值
        double baiy = y * 1.0;
        double baiz = z * 1.0;
        double fen = baiy / baiz;
        // NumberFormat nf = NumberFormat.getPercentInstance();注释掉的也是一种方法
        // nf.setMinimumFractionDigits( 2 ); 保留到小数点后几位
        DecimalFormat df1 = new DecimalFormat("##%");
        // ##.00%
        // 百分比格式，后面不足2位的用0补齐
        // baifenbi=nf.format(fen);
        baifenbi = df1.format(fen);
        System.out.println(baifenbi);
        return baifenbi;
    }


    @Override
    public List<TaskShow> selectTaskShowList(TaskShow taskShow, Long userId)
    {
        List<TaskShow> taskShowList = null;
        // 管理员显示所有菜单信息
        if (SysUser.isAdmin(userId))
        {
            taskShowList = taskShowMapper.selectTaskShowList(taskShow);
        }
        else
        {
//            taskShow.getParams().put("userId", userId);
//            taskShowList = taskShowMapper.selectTaskShowListByUserId(taskShow);
        }
        return taskShowList;
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param taskShow 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertTaskShow(TaskShow taskShow)
    {
        //判断是否重名
        List<TaskShow> taskShows = taskShowMapper.selectTaskByTitle(taskShow);
        if(taskShows.size()>0){
            taskShow.setTitle(taskShow.getTitle()+System.currentTimeMillis());
        }
        //时间校验,不能小于子项目时间不能大于父项目时间
        AjaxBean ajaxBean = dateDispos(taskShow);
        if(!ajaxBean.getStatus()){
         ajaxBean.getMsg();
         return 0;
        }
        //完善新增数据
        taskShow.setId(IdGen.uuid());
        taskShow.setCreateTime(DateUtils.getNowDate());
        //计算工期
        taskShow.setWorkDay(sumDay(taskShow));
        int i = taskShowMapper.insertTaskShow(taskShow);
        //更新状态
        updateSp(taskShow);
        return i;
    }


    /**
     * 修改【请填写功能名称】
     *
     * @param taskShow 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateTaskShow(TaskShow taskShow)
    {
        taskShow.setUpdateName(taskShow.getCreateName());
        taskShow.setUpdateTime(DateUtils.getNowDate());
        taskShow.setWorkDay(sumDay(taskShow));
        int i = taskShowMapper.updateTaskShow(taskShow);
        //修改百分比
        updateSp(taskShow);
        return i;
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTaskShowByIds(String[] ids)
    {
        return taskShowMapper.deleteTaskShowByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTaskShowById(String id)
    {
        //查询该任务
        TaskShow taskShow = taskShowMapper.selectTaskShowById(id);
        //查询该任务父节点
        TaskShow parentTask = findByParentId(taskShow);
        //删除该节点
        int i = taskShowMapper.deleteTaskShowById(id);
        //更新父节点下的状态
        updateTaskShow(parentTask);
        return i;

    }


    /**
     * @Description //TODO 判断是否存在子菜单
     * @Author liujiaji
     * @Date 2022/6/22 10:39
     * @Param [id]
     * @return int
     **/
    @Override
    public boolean hasChildById(String id)
    {
        int result = taskShowMapper.hasChildById(id);
        return result > 0;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param taskShows 任务展示列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TaskShowTreeSelect> buildTaskShowTreeSelect(List<TaskShow> taskShows)
    {
        List<TaskShow> taskShowTrees = buildTaskShowTree(taskShows);
        return taskShowTrees.stream().map(TaskShowTreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     *
     * @param taskShows 任务展示列表
     * @return 树结构列表
     */
    @Override
    public List<TaskShow> buildTaskShowTree(List<TaskShow> taskShows)
    {
        List<TaskShow> returnList = new ArrayList<TaskShow>();
        List<String> tempList = new ArrayList<String>();
        for (TaskShow taskShow : taskShows)
        {
            tempList.add(taskShow.getId());
        }
        for (Iterator<TaskShow> iterator = taskShows.iterator(); iterator.hasNext();)
        {
            TaskShow taskShow = (TaskShow) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(taskShow.getParentId()))
            {
                recursionFn(taskShows, taskShow);
                returnList.add(taskShow);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = taskShows;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<TaskShow> list, TaskShow t)
    {
        // 得到子节点列表
        List<TaskShow> childList = getChildList(list, t);
        t.setChildren(childList);
        for (TaskShow tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<TaskShow> getChildList(List<TaskShow> list, TaskShow t)
    {
        List<TaskShow> tlist = new ArrayList<TaskShow>();
        Iterator<TaskShow> it = list.iterator();
        while (it.hasNext())
        {
            TaskShow n = (TaskShow) it.next();
            if (n.getParentId().equals(t.getId()))
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<TaskShow> list, TaskShow t)
    {
        return getChildList(list, t).size() > 0;
    }


    /**
     * @Description //TODO 计算工期
     * @Author liujiaji
     * @Date 2022/6/27 14:15
     * @Param []
     * @return void
     **/
    public static String sumDay(TaskShow taskShow){
        Date taskStartDate = taskShow.getTaskStartDate();
        Date endDate = taskShow.getTaskEndDate();
        long sTime = taskStartDate.getTime();
        long eTime1 = endDate.getTime();
        long wd = eTime1-sTime;
        long i = 1000*60*60*24;
        long r = wd/i;
        return String.valueOf(r+1);
    }

    /**
     * @Description //TODO 递归查找父项目
     * @Author liujiaji
     * @Date 2022/6/27 15:43
     * @Param [taskShow]
     * @return com.ruoyi.system.domain.TaskShow
     **/
    public TaskShow findByParentId(TaskShow taskShow){
        List<TaskShow> taskShows = taskShowMapper.selectTaskShowByParentId(taskShow);
        if(!taskShows.isEmpty()){
            for (int i = 0; i < taskShows.size(); i++) {
                return findByParentId(taskShows.get(i));
            }
        }
        return taskShow;
    }

    /**
     * @Description //TODO 更新百分比
     * @Author liujiaji
     * @Date 2022/6/27 13:44
     * @Param [taskShow]
     * @return int
     **/
    public Map<String, String> updateTaskShowSp(TaskShow taskShow){
        //查询子任务
        Map<String, String> rsMap = new HashedMap();
        int wdays = 0;
        int totaldays = 0;
        List<TaskShow> taskShows = taskShowMapper.selectTaskShowBychildId(taskShow);
        if(taskShows.size()==0){
            //没有子项目
            if("2".equals(taskShow.getState())){
                taskShow.setSchedulePercent("100%");
                wdays = Integer.valueOf(taskShow.getWorkDay());
            }else{
                taskShow.setSchedulePercent("0%");
            }
            totaldays = Integer.valueOf(taskShow.getWorkDay());
            taskShowMapper.updateTaskShow(taskShow);
        }
        for (int i = 0; i < taskShows.size(); i++) {
            //循环调用
            Map<String, String> resMap = updateTaskShowSp(taskShows.get(i));
            String wdays1 = resMap.get("wdays");
            String totaldays1 = resMap.get("totaldays");
            wdays += Integer.valueOf(wdays1);
            totaldays += Integer.valueOf(totaldays1);
            //设置百分比及百分比计算及状态
            String s = myPercent(wdays,totaldays);
            if("100%".equals(s)){
                taskShow.setState("2");
            }else{
                taskShow.setState("1");
            }
            taskShow.setSchedulePercent(s);
            taskShowMapper.updateTaskShow(taskShow);
        }
        rsMap.put("wdays",String.valueOf(wdays));
        rsMap.put("totaldays", String.valueOf(totaldays));
        return rsMap;
    }

    /**
     * @Description //TODO 更改百分比及状态封装 只能对所存在数据进行修改不可对新增新数据修改
     * @Author liujiaji
     * @Date 2022/6/28 9:16
     * @Param [taskShow]
     * @return void
     **/
    public void updateSp(TaskShow taskShow){
        TaskShow taskShowp = findByParentId(taskShow);
        updateTaskShowSp(taskShowp);
    }

    /**
     * @Description //TODO 项目时间范围判断
     * @Author liujiaji
     * @Date 2022/6/28 15:28
     * @Param [taskShow]
     * @return com.ruoyi.factory.domain.AjaxBean
     **/
    @Override
    public AjaxBean dateDispos(TaskShow taskShow){
        long stime2 = taskShow.getTaskStartDate().getTime();
        long etime3 = taskShow.getTaskEndDate().getTime();
        //查询是否有父类 该时间不可超过父类时间范围
        List<TaskShow> taskShows = taskShowMapper.selectTaskShowByParentId(taskShow);
        if(taskShows.size() > 0){
            long sptime = taskShows.get(0).getTaskStartDate().getTime();
            long eptime1 = taskShows.get(0).getTaskEndDate().getTime();
            if(stime2<sptime || etime3>eptime1){
                return new AjaxBean("选择时间不可超出父项目范围",false);
            }
        }
        //查询子项目时间不可小于子项目时间
        List<TaskShow> taskShows1 = taskShowMapper.selectTaskShowBychildId(taskShow);
        if(taskShows1.size()>0){
            //获取到范围最大的子项目时间
            long sztime = 0;
            long eztime = 0;
            for (TaskShow show : taskShows1) {
                long szt = show.getTaskStartDate().getTime();
                long ezt = show.getTaskEndDate().getTime();
                if(szt <= sztime || sztime ==0){
                    sztime =szt;
                }
                if(ezt >= eztime || eztime==0){
                    eztime = ezt;
                }
            }
            //判断时间
            if(stime2 > sztime || etime3 < eztime){
                return new AjaxBean("选择时间需大于子项目范围",false);
            }
        }
        return new AjaxBean("成功", true);
    }
}
